package com.mingqijia.gassafety.job.job.warnStrategy;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.util.StringUtil;
import com.mingqijia.gassafety.authority.api.resp.config.DictionaryItemRespDTO;
import com.mingqijia.gassafety.authority.dal.helper.ConfigureHolder;
import com.mingqijia.gassafety.db.entity.*;
import com.mingqijia.gassafety.db.mapper.*;
import com.mingqijia.gassafety.job.dto.CallTaskDTO;
import com.mingqijia.gassafety.job.dto.SendMessageDTO;
import com.mingqijia.gassafety.job.service.EquipmentService;
import com.mingqijia.gassafety.job.service.impl.CompanyServiceImpl;
import com.mingqijia.gassafety.job.service.impl.XFCallServiceImpl;
import com.mingqijia.gassafety.shared.constant.BusinessNoticeParam;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.ConsumerServiceStatusEnum;
import com.mingqijia.gassafety.shared.constant.EquipmentType;
import com.mingqijia.gassafety.shared.dto.AssembleTemplateDTO;
import com.mingqijia.gassafety.shared.dto.TaskDetailParamDTO;
import com.mingqijia.gassafety.shared.dto.TaskDetailRespDTO;
import com.mingqijia.gassafety.shared.utils.RedisCacheExt;
import com.mingqijia.gassafety.shared.utils.commonUtils.DateUtils;
import com.mingqijia.gassafety.shared.utils.message.SendMessageService;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.mingqijia.gassafety.shared.constant.TableConst.dtu;

/**
 * @author zhangfei
 * @version 1.0.0
 * @ClassName MessageReceiptCompensateJob.java
 * @Description 短信错误补偿
 * @createTime 2022年03月29日
 */
@Configuration
@EnableScheduling
@Component
@Slf4j
public class MessageReceiptCompensateJob {
    @Autowired
    RedisCacheExt redisUtil;
    @Autowired
    WarningRecordMapper warningRecordMapper;
    @Autowired
    SendMessageService sendMessageService;
    @Autowired
    XFCallServiceImpl xfCallService;
    @Autowired
    CompanyServiceImpl companyService;

    @Autowired
    RunningRecordMapper runningRecordMapper;
    @Autowired
    InformRecordMapper informRecordMapper;

    @Autowired
    WarnStrategyMapper warnStrategyMapper;

    @Autowired
    RunningStrategyExtMapper runningStrategyExtMapper;

    @Autowired
    RunningStrategyMapper runningStrategyMapper;

    @Autowired
    DtuMapper dtuMapper;

    @Autowired
    ConsumerMapper consumerMapper;

    @Autowired
    BusinessNoticeMapper noticeMapper;

    @Autowired
    ConfigureHolder holder;

    @Autowired
    ConsumerServiceInfoMapper consumerServiceInfoMapper;

    public static final String OUTBOUND_CALL_MSG_NOTICE = "outbound_call_msg_notice";

    @Autowired
    private EquipmentService equipmentService;

    /**
     * 补偿
     */
//    @XxlJob("messageReceiptCompensateJob")
    @Scheduled(cron = "${gassafety.warnStrategy.job.messageReceiptCompensate}")
    public ReturnT<String> messageReceiptCompensateJob() {
//        XxlJobLogger.log("XXLJOB-messageReceiptCompensateJob start...param: {}", param);
        log.info("messageReceiptCompensateJob--start--------");
        //防重复锁
        String key = Constants.STRATEGY_RECORD_STATE_COMMON;
        try {
            Boolean acquire = redisUtil.setIfAbsent(key, String.valueOf(System.currentTimeMillis()), Constants.TIME_OUT);//15分钟超时
            if (acquire) {
                //扫描所有异常数据
                try {

                    List<WarningRecord> warningRecords = warningRecordMapper.selectLists(
                            DateUtil.offsetDay(new Date(), -1).toDateStr()
                    );
                    log.info("messageReceiptCompensateJob-warningRecords:{}", JSONObject.toJSONString(warningRecords));
                    if (!CollectionUtil.isEmpty(warningRecords)) {
                        warningRecords.forEach(warningRecord -> {
                            HashMap<String, Object> req = new HashMap<>();
                            req.put("ids", JSONArray.parseArray(warningRecord.getReceiptCode()));
                            String orgCode = companyService.getOrgCode(warningRecord.getSpId(), warningRecord.getConsumerId());
                            req.put("orgCode", orgCode);
                            Map<String, Object> map = sendMessageService.subTaskDetail(req, "");
                            log.info("messageReceiptCompensateJob-map:{}", JSONObject.toJSONString(map));
                            warningRecord.setNotifyFrom(0);
                            if (map != null && !StringUtils.isEmpty(map.get("errorMsg"))) {
                                warningRecord.setRemark(map.get("errorMsg") + "");
                                warningRecord.setSendResult(1);
                                warningRecordMapper.updateById(warningRecord);
                                log.info("messageReceiptCompensateJob-本次补偿数据：{}", warningRecord);
                            } else {
                                warningRecord.setSendResult(0);
                                warningRecordMapper.updateById(warningRecord);
                                log.info("messageReceiptCompensateJob-本次纠正数据：{}", warningRecord);
                            }
                        });
                    }
                } catch (Exception e) {
                    log.info("messageReceiptCompensateJob-error:{}", e);
                } finally {
                    redisUtil.del(key);
                }
            }
        } catch (Exception e) {
            log.info("messageReceiptCompensateJob-error:{}", e);
        }
        log.info("messageReceiptCompensateJob--end--------");
        return ReturnT.SUCCESS;
    }

    @Scheduled(cron = "${gassafety.warnStrategy.job.messageReceiptCompensate}")
    public ReturnT<String> messageServicePeriodJob() {
//        XxlJobLogger.log("XXLJOB-messageReceiptCompensateJob start...param: {}", param);
        log.info("messageServicePeriodJob--start--------");
        //防重复锁
        String key = Constants.STRATEGY_RECORD_SERVICE_PERIOD;
        try {
            Boolean acquire = redisUtil.setIfAbsent(key, String.valueOf(System.currentTimeMillis()), Constants.TIME_OUT);//15分钟超时
            if (acquire) {
                //扫描所有异常数据
                try {
                    List<InformRecord> informRecords = informRecordMapper.selectLists(
                            DateUtil.offsetDay(new Date(), -1).toDateStr()
                    );
                    List<RunningRecord> runningRecords = runningRecordMapper.selectLists(
                            DateUtil.offsetDay(new Date(), -1).toDateStr()
                    );
                    try {
                        Thread.sleep(5000L);
                    } catch (InterruptedException e) {
                        log.error("messageServicePeriodJob-sleep:{}", e);
                    }
                    log.info("messageServicePeriodJob-informRecords:{}，size:{}", JSONObject.toJSONString(informRecords), informRecords.size());
                    if (!CollectionUtil.isEmpty(informRecords)) {
                        informRecords.forEach(warningRecord -> {
                            HashMap<String, Object> req = new HashMap<>();
                            req.put("ids", JSONArray.parseArray(warningRecord.getReceiptCode()));
                            String orgCode = companyService.getOrgCode(warningRecord.getSpId(), warningRecord.getConsumerId());
                            req.put("orgCode", orgCode);
                            Map<String, Object> map = sendMessageService.subTaskDetail(req, "");
                            log.info("messageServicePeriodJob-req:{},map:{}", req, JSONObject.toJSONString(map));
                            if (map != null && !StringUtils.isEmpty(map.get("errorMsg")) && !"report time out".equals(map.get("errorMsg").toString())) {
                                warningRecord.setRemark(map.get("errorMsg") + "");
                                warningRecord.setSendResult(1);
                                warningRecord.setStatus(1);
                                informRecordMapper.updateById(warningRecord);
                                log.info("messageServicePeriodJob-本次补偿数据：{}", warningRecord);
                            } else {
                                warningRecord.setSendResult(0);
                                warningRecord.setStatus(1);
                                informRecordMapper.updateById(warningRecord);
                                log.info("messageServicePeriodJob-本次纠正数据：{}", warningRecord);
                            }
                        });
                    }
                    if (!CollectionUtil.isEmpty(runningRecords)) {
                        runningRecords.forEach(runningRecord -> {
                            HashMap<String, Object> req = new HashMap<>();
                            req.put("ids", JSONArray.parseArray(runningRecord.getReceiptCode()));
                            String orgCode = companyService.getOrgCode(runningRecord.getSpId(), runningRecord.getConsumerId());
                            req.put("orgCode", orgCode);
                            Map<String, Object> map = sendMessageService.subTaskDetail(req, "");
                            log.info("messageServicePeriodJob-req:{},map:{}", req, JSONObject.toJSONString(map));
                            if (map != null && !StringUtils.isEmpty(map.get("errorMsg")) && !"report time out".equals(map.get("errorMsg").toString())) {
                                runningRecord.setRemark(map.get("errorMsg") + "");
                                runningRecord.setSendResult(1);
                                runningRecord.setStatus(1);
                                runningRecordMapper.updateById(runningRecord);
                                log.info("messageServicePeriodJob-runningRecord本次补偿数据：{}", runningRecord);
                            } else {
                                runningRecord.setSendResult(0);
                                runningRecord.setStatus(1);
                                runningRecordMapper.updateById(runningRecord);
                                log.info("messageServicePeriodJob-本次纠正数据：{}", runningRecord);
                            }
                        });
                    }
                } catch (Exception e) {
                    log.info("messageServicePeriodJob-error:{}", e);
                } finally {
                    redisUtil.del(key);
                }
            }
        } catch (Exception e) {
            log.info("messageServicePeriodJob-error:{}", e);
        }
        log.info("messageServicePeriodJob--end--------");
        return ReturnT.SUCCESS;
    }


    /**
     * 定时拉取外呼回执信息
     */
    @Scheduled(cron = "${gassafety.warnStrategy.job.messageReceiptCompensate}")
    public void callReceiptCompensateJob() {
        log.info("callReceiptCompensateJob--start--------");
        //防重复锁
        String key = Constants.STRATEGY_RECORD_STATE_CALL;
        try {
            Boolean acquire = redisUtil.setIfAbsent(key, String.valueOf(System.currentTimeMillis()), Constants.TIME_OUT);//15分钟超时
            log.info("callReceiptCompensateJob-acquire:{}", acquire);
            if (acquire) {
                //扫描所有数据
                try {
                    List<WarningRecord> warningRecords = warningRecordMapper.selectCallLists();
                    List<RunningRecord> runningRecords = runningRecordMapper.selectCallLists();
                    List<InformRecord> informRecords = informRecordMapper.selectCallLists();
                    log.info("warningRecords:{},runningRecords:{},informRecords:{}",
                            JSONObject.toJSONString(warningRecords), JSONObject.toJSONString(runningRecords), JSONObject.toJSONString(informRecords));
                    List<Integer> ids = new ArrayList<>();
                    Map<String, WarningRecord> warningRecordMap = new HashMap<>();
                    warningRecords.forEach(warningRecord -> {
                        String receiptCode = warningRecord.getReceiptCode();
                        warningRecordMap.put(warningRecord.getReceiptCode(), warningRecord);
                        if (!StringUtils.isEmpty(receiptCode)) {
                            try {
                                ids.add(Integer.parseInt(receiptCode));
                            } catch (Exception e) {
                                log.error("receiptCode不能转成BigInteger" + receiptCode);
                            }
                        }


                    });
                    Map<String, String> warningMap = queryCallInfo(ids, 0);
                    if (MapUtils.isNotEmpty(warningMap)) {
                        warningSendSms(warningMap, warningRecordMap);
                    }
                    List<Integer> runnings = new ArrayList<>();
                    Map<String, RunningRecord> runningRecordMap = new HashMap<>();
                    runningRecords.forEach(warningRecord -> {
                        String receiptCode = warningRecord.getReceiptCode();
                        runningRecordMap.put(receiptCode, warningRecord);
                        if (!StringUtils.isEmpty(receiptCode)) {
                            try {
                                runnings.add(Integer.parseInt(receiptCode));
                            } catch (Exception e) {
                                log.error("receiptCode不能转成BigInteger" + receiptCode);
                            }
                        }

                    });
                    Map<String, String> runningMap = queryCallInfo(runnings, 1);
                    if (MapUtils.isNotEmpty(runningMap)) {
                        runningSendSms(runningMap, runningRecordMap);
                    }
                    List<Integer> informs = new ArrayList<>();
                    Map<String, InformRecord> informRecordMap = new HashMap<>();
                    informRecords.forEach(warningRecord -> {
                        String receiptCode = warningRecord.getReceiptCode();
                        informRecordMap.put(receiptCode, warningRecord);
                        if (!StringUtils.isEmpty(receiptCode)) {
                            try {
                                informs.add(Integer.parseInt(receiptCode));
                            } catch (Exception e) {
                                log.error("receiptCode不能转成BigInteger" + receiptCode);
                            }
                        }

                    });
                    Map<String, String> informMap = queryCallInfo(informs, 2);
                    if (MapUtils.isNotEmpty(informMap)) {
                        informSendSms(informMap, informRecordMap);
                    }
                } catch (Exception e) {
                    log.info("callReceiptCompensateJob-error:{}", e);
                } finally {
                    redisUtil.del(key);
                }
            }
        } catch (Exception e) {
            log.info("callReceiptCompensateJob-error:{}", e);
        }
        log.info("callReceiptCompensateJob--end--------");

    }

    //报警记录发送短信
    public void warningSendSms(Map<String, String> warningMap, Map<String, WarningRecord> warningRecordMap) {
        for (String taskId : warningMap.keySet()) {
            if (warningRecordMap.containsKey(taskId)) {
                WarningRecord warningRecord = warningRecordMap.get(taskId);
                log.info("开始进入发送短信2:{}", JSONObject.toJSONString(warningRecord));
                if (warningRecord != null && warningRecord.getSendType() == 4 && !StringUtils.isEmpty(warningRecord.getTriggerRuleId())) {
                    String warning = warningMap.get(taskId);
                    log.info("开始进入发送短信3:{}", JSONObject.toJSONString(warning));
                    //当外呼未被接通/被挂断时即时推送短信提醒
                    if (StringUtils.pathEquals(warning, "3") || StringUtils.pathEquals(warning, "5") || StringUtils.pathEquals(warning, "8") || StringUtils.pathEquals(warning, "20")) {
                        //查询当前报警记录的报警策略是否需要发送端
                        WarnStrategy warnStrategy = warnStrategyMapper.selectById(warningRecord.getTriggerRuleId());
                        Map<String, Object> qMap = new HashMap<>();
                        qMap.put("spId", warningRecord.getSpId());
                        qMap.put("paramCode", OUTBOUND_CALL_MSG_NOTICE);
                        List<BusinessNotice> noticeList = noticeMapper.selectParamList(qMap);
                        if ((warnStrategy != null && ((warningRecord.getType() == 1 && warnStrategy.getLowCallSendNote() == 0) || (warningRecord.getType() == 2 && warnStrategy.getHighCallSendNote() == 0))) || (!CollectionUtils.isEmpty(noticeList) && StringUtils.pathEquals("ON", noticeList.get(0).getParamValue()))) {

                            //String callPhones = warnStrategyExt.getCallPhones();
                            String pushPhone = warningRecord.getPushPhone();
                            //当外呼手机号不为空时才需要发送
                            if (!StringUtils.isEmpty(pushPhone)) {
//                                List<String> phones = new ArrayList<>();
//                                String[] split = callPhones.split(WarnStrategyJob.split);
//                                for (String s : split) {
//                                    phones.add(s);
//                                }
                                LambdaQueryWrapper<Dtu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                                lambdaQueryWrapper.eq(Dtu::getIMEI, warningRecord.getIMEI()).eq(Dtu::getIsDeleted, 0);
                                Dtu dtu = dtuMapper.selectOne(lambdaQueryWrapper);
                                Map<String, Object> param = new HashMap<>();
                                if (dtu != null) {
                                    param.put("Name", StringUtils.isEmpty(dtu.getName()) ? "": dtu.getName());
                                    param.put("Position", dtu.getInstallationPosition());
                                    if (!StringUtils.isEmpty(dtu.getEquipmentType())) {
                                        DictionaryItemRespDTO equipmentTypeDict = holder.getDictionaryByKey(
                                                EquipmentType.DICT_CODE, dtu.getSpId()).stream().filter(a -> a.getValue().equals(
                                                dtu.getEquipmentType())).collect(Collectors.toList()).get(0);
                                        param.put("Equipmenttype", equipmentTypeDict.getName());
                                    }
                                    param.put("IMEI", dtu.getIMEI());
                                    param.put("Time", warningRecord.getWarningStartTime() == null ? "" : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(warningRecord.getWarningStartTime()));
                                    if (dtu.getConsumerId() > 0) {
                                        LambdaQueryWrapper<Consumer> consumerWrapper = new LambdaQueryWrapper<>();
                                        consumerWrapper.eq(Consumer::getId, dtu.getConsumerId()).eq(Consumer::getIsDeleted, 0);
                                        Consumer consumer = consumerMapper.selectOne(consumerWrapper);
                                        if (consumer != null) {
                                            param.put("subsName", consumer.getCustName());
                                            param.put("address", consumer.getCustAddress());
                                        }
                                    }
                                    String factoryName = equipmentService.getEquipmentManufacturerName(dtu.getEquipmentManufacturer(),dtu.getSpId());
                                    param.put("factoryName", factoryName);
                                }

                                // 公司电话
                                QueryWrapper<BusinessNotice> query = new QueryWrapper<>();
                                query.lambda().or().eq(BusinessNotice::getIsDeleted, 0)
                                        .eq(BusinessNotice::getSpId, warningRecord.getSpId())
                                        .eq(BusinessNotice::getParamCode, BusinessNoticeParam.CM_SERVICE_HOT_LINE.getCode());
                                List<BusinessNotice> r = noticeMapper.selectList(query);
                                String phone = "";
                                if (!CollectionUtil.isEmpty(r)) phone = r.get(0).getParamValue();
                                param.put("phone", phone);
                                //调用外部短信接口
                                String orgCode = companyService.getOrgCode(warningRecord.getSpId(), warningRecord.getConsumerId());
                                Map<String, Object> requestParam = sendMessageService
                                        .getRequestParam(pushPhone
                                                , Constants.WARN_ALARM_STRATEGY, orgCode
                                                , param, "sms", null, null, null, 0);
                                log.info("报警记录外呼开始发送短信callSms-ext:{}", JSONObject.toJSONString(requestParam));
                                Map<String, Object> sms = sendMessageService
                                        .sendSms(requestParam, warningRecord.getSpId());
                                log.info("报警记录外呼开始发送短信-发送日志:{}", JSONObject.toJSONString(sms));
                                AssembleTemplateDTO assembleTemplateDTO = new AssembleTemplateDTO();
                                assembleTemplateDTO.setSpId(warningRecord.getSpId());
                                assembleTemplateDTO.setOrgCode(orgCode);
                                String content = sendMessageService.getSmsContent(Constants.WARN_ALARM_STRATEGY,param,assembleTemplateDTO);
                                if (sms.get("result").equals(true)) {
                                    //发送成功
                                    String errorMsg = "";
                                    if (sms.get("data") != null) {
                                        HashMap<String, Object> req = new HashMap<>();
                                        req.put("ids", sms.get("data"));
                                        req.put("orgCode", orgCode);
                                        try {
                                            Thread.sleep(2000L);
                                            Map<String, Object> resMap = sendMessageService.subTaskDetail(req, "");
                                            //延迟获取数据
                                            errorMsg = resMap != null ? (String) resMap.get("errorMsg") : "";
                                        } catch (InterruptedException e) {
                                            log.error("subTaskDetail-error:{}", e);
                                        }
                                    }
                                    saveWarningRecord(content, errorMsg, JSONObject.toJSONString(sms.get("data")), warningRecord);
                                } else {
                                    String errMsg = (String)sms.get("errMsg");
                                    saveWarningRecord(content, errMsg, JSONObject.toJSONString(sms.get("data")), warningRecord);
                                }
                            }


                        }

                    }
                }
            }

        }
    }

    //故障离线服务到期发送短信
    public void runningSendSms(Map<String, String> informMap, Map<String, RunningRecord> runningRecordMap) {
        for (String taskId : informMap.keySet()) {
            if (runningRecordMap.containsKey(taskId)) {
                RunningRecord runningRecord = runningRecordMap.get(taskId);
                log.info("运行报告开始进入发送短信1:{}", JSONObject.toJSONString(runningRecord));
                if (runningRecord != null && runningRecord.getSendType() == 3 && !StringUtils.isEmpty(runningRecord.getTriggerRuleId())) {
                    String running = informMap.get(taskId);
                    log.info("运行报告开始进入发送短信2:{}", JSONObject.toJSONString(running));
                    //当外呼未被接通/被挂断时即时推送短信提醒
                    if (StringUtils.pathEquals(running, "3") || StringUtils.pathEquals(running, "5") || StringUtils.pathEquals(running, "8") || StringUtils.pathEquals(running, "20")) {
                        //查询当前报警记录的报警策略是否需要发送端
                        LambdaQueryWrapper<RunningStrategyExt> runningWrapper = new LambdaQueryWrapper<>();
                        runningWrapper.eq(RunningStrategyExt::getStrategyId, runningRecord.getTriggerRuleId())
                                .eq(RunningStrategyExt::getPushType, 3)
                                .eq(RunningStrategyExt::getIsDeleted, 0);
                        RunningStrategyExt runningStrategyExt = runningStrategyExtMapper.selectOne(runningWrapper);
                        if (runningStrategyExt != null && runningStrategyExt.getCallSendNote() == 0) {
                            String pushPhone = runningRecord.getPushPhone();
                            //当外呼手机号不为空时才需要发送
                            if (!StringUtils.isEmpty(pushPhone)) {
                                Map<String, Object> param = new HashMap<>();
                                if (!StringUtils.isEmpty(runningRecord.getConsumerId())) {
                                    LambdaQueryWrapper<Consumer> consumerWrapper = new LambdaQueryWrapper<>();
                                    consumerWrapper.eq(Consumer::getId, runningRecord.getConsumerId()).eq(Consumer::getIsDeleted, 0);
                                    Consumer consumer = consumerMapper.selectOne(consumerWrapper);
                                    if (consumer != null) {
                                        param.put("subsName", consumer.getCustName());
                                        param.put("address", consumer.getCustAddress());
                                    }
                                }
                                // 公司电话
                                QueryWrapper<BusinessNotice> query = new QueryWrapper<>();
                                query.lambda().or().eq(BusinessNotice::getIsDeleted, 0)
                                        .eq(BusinessNotice::getSpId, runningRecord.getSpId())
                                        .eq(BusinessNotice::getParamCode, BusinessNoticeParam.CM_SERVICE_HOT_LINE.getCode());
                                List<BusinessNotice> r = noticeMapper.selectList(query);
                                String phone = "";
                                if (!CollectionUtil.isEmpty(r)) phone = r.get(0).getParamValue();
                                param.put("phone", phone);
                                param.put("#Time#", runningRecord.getStartTime() == null ? "" : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(runningRecord.getStartTime()));
                                //调用外部短信接口
                                String orgCode = companyService.getOrgCode(runningRecord.getSpId(), runningRecord.getConsumerId());
                                Map<String, Object> requestParam = sendMessageService
                                        .getRequestParam(pushPhone
                                                , Constants.RUNNING_ALARM_STRATEGY, orgCode
                                                , param, "sms", null, null, null, 0);
                                log.info("报警记录外呼开始发送短信callSms-ext:{}", JSONObject.toJSONString(requestParam));
                                Map<String, Object> sms = sendMessageService
                                        .sendSms(requestParam, runningRecord.getSpId());
                                log.info("报警记录外呼开始发送短信-发送日志:{}", JSONObject.toJSONString(sms));
                                //查询短信内容
                                TaskDetailParamDTO smsTaskDetailParam = new TaskDetailParamDTO();
                                smsTaskDetailParam.setSpId(runningRecord.getSpId());
                                smsTaskDetailParam.setOrgCode(orgCode);
                                smsTaskDetailParam.setCode(Constants.RUNNING_ALARM_STRATEGY);
                                TaskDetailRespDTO smsTaskDetailResp = sendMessageService.getMsgTemplateContent(smsTaskDetailParam);
                                String contents = smsTaskDetailResp.getTemplateContent();
                                if (sms.get("result").equals(true)) {
                                    //发送成功
                                    String errorMsg = "发送成功";
                                    if (sms.get("data") != null) {
                                        HashMap<String, Object> req = new HashMap<>();
                                        req.put("ids", sms.get("data"));
                                        req.put("orgCode", orgCode);
                                        try {
                                            Thread.sleep(2000L);
                                            Map<String, Object> resMap = sendMessageService.subTaskDetail(req, "");
                                            //延迟获取数据
                                            errorMsg = resMap != null ? (String) resMap.get("errorMsg") : "";
                                        } catch (InterruptedException e) {
                                            log.error("subTaskDetail-error:{}", e);
                                        }

                                    }
                                    saveRunningRecord(contents, errorMsg, JSONObject.toJSONString(sms.get("data")), runningRecord);
                                }else {
                                    String errMsg = (String)sms.get("errMsg");
                                    saveRunningRecord(contents, errMsg, JSONObject.toJSONString(sms.get("data")), runningRecord);
                                }
                            }

                        }

                    }
                }
            }

        }
    }

    //故障离线服务到期发送短信
    public void informSendSms(Map<String, String> informMap, Map<String, InformRecord> informRecordMap) {
        log.info("开始进入发送短信1:{}", JSONObject.toJSONString(informMap));
        for (String taskId : informMap.keySet()) {
            log.info("开始进入发送短信2:{}", JSONObject.toJSONString(informRecordMap));
            if (informRecordMap.containsKey(taskId)) {
                InformRecord informRecord = informRecordMap.get(taskId);
                log.info("开始进入发送短信3:{}", JSONObject.toJSONString(informRecord));
                if (informRecord != null && informRecord.getSendType() == 3 && !StringUtils.isEmpty(informRecord.getTriggerRuleId())) {
                    String running = informMap.get(taskId);
                    log.info("开始进入发送短信4:{}", JSONObject.toJSONString(running));
                    //当外呼未被接通/被挂断时即时推送短信提醒
                    if (StringUtils.pathEquals(running, "3") || StringUtils.pathEquals(running, "5") || StringUtils.pathEquals(running, "8") || StringUtils.pathEquals(running, "20")) {
                        //查询当前报警记录的报警策略是否需要发送端
                        RunningStrategy runningStrategy = runningStrategyMapper.selectById(informRecord.getTriggerRuleId());
                        LambdaQueryWrapper<RunningStrategyExt> runningWrapper = new LambdaQueryWrapper<>();
                        runningWrapper.eq(RunningStrategyExt::getStrategyId, informRecord.getTriggerRuleId())
                                .eq(RunningStrategyExt::getPushType, 3)
                                .eq(RunningStrategyExt::getIsDeleted, 0);
                        List<RunningStrategyExt> runningStrategyExts = runningStrategyExtMapper.selectList(runningWrapper);
                        log.info("开始进入发送短信5:{}", JSONObject.toJSONString(runningStrategyExts));
                        if (!CollectionUtil.isEmpty(runningStrategyExts)) {
                            RunningStrategyExt runningStrategyExt = runningStrategyExts.get(0);
                            if (runningStrategyExt != null && runningStrategyExt.getCallSendNote() == 0) {
                                String pushPhone = informRecord.getPushPhone();
                                //当外呼手机号不为空时才需要发送
                                if (!StringUtils.isEmpty(pushPhone)) {
                                    LambdaQueryWrapper<Dtu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                                    lambdaQueryWrapper.eq(Dtu::getIMEI, informRecord.getIMEI()).eq(Dtu::getIsDeleted, 0);
                                    Dtu dtu = dtuMapper.selectOne(lambdaQueryWrapper);
                                    Map<String, Object> param = new HashMap<>();
                                    if (dtu != null) {
                                        param.put("Name", StringUtils.isEmpty(dtu.getName())? "": dtu.getName());
                                        param.put("Position", dtu.getInstallationPosition());
                                        if (!StringUtils.isEmpty(dtu.getEquipmentType())) {
                                            DictionaryItemRespDTO equipmentTypeDict = holder.getDictionaryByKey(
                                                    EquipmentType.DICT_CODE, dtu.getSpId()).stream().filter(a -> a.getValue().equals(
                                                    dtu.getEquipmentType())).collect(Collectors.toList()).get(0);
                                            param.put("Equipmenttype", equipmentTypeDict.getName());
                                        }
                                        param.put("IMEI", dtu.getIMEI());
                                        if (dtu.getConsumerId() > 0) {
                                            LambdaQueryWrapper<Consumer> consumerWrapper = new LambdaQueryWrapper<>();
                                            consumerWrapper.eq(Consumer::getId, dtu.getConsumerId()).eq(Consumer::getIsDeleted, 0);
                                            Consumer consumer = consumerMapper.selectOne(consumerWrapper);
                                            if (consumer != null) {
                                                param.put("subsName", consumer.getCustName());
                                                param.put("address", consumer.getCustAddress());
                                            }
                                        }
                                        String factoryName = equipmentService.getEquipmentManufacturerName(dtu.getEquipmentManufacturer(),dtu.getSpId());
                                        param.put("factoryName",factoryName);
                                    }
                                    param.put("Time", informRecord.getStartTime() == null ? "" : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(informRecord.getStartTime()));
                                    //调用外部短信接口
                                    String msgType = Constants.FAULT_ALARM_STRATEGY;
                                    if (runningStrategy != null) {
                                        if (runningStrategy.getStrategyType() == 0) {
                                            msgType = Constants.FAULT_ALARM_STRATEGY;
                                        } else if (runningStrategy.getStrategyType() == 1) {
                                            msgType = Constants.REST_ALARM_STRATEGY;
                                        } else {
                                            msgType = Constants.SERVICE_ALARM_STRATEGY;
                                            QueryWrapper<ConsumerServiceInfo> queryWrapper = new QueryWrapper<>();

                                            queryWrapper.lambda().eq(ConsumerServiceInfo::getSpId, informRecord.getSpId())
                                                    .eq(ConsumerServiceInfo::getConsumerId, informRecord.getConsumerId())
                                                    .eq(ConsumerServiceInfo::getImei, informRecord.getIMEI())
                                                    .eq(ConsumerServiceInfo::getIsDeleted, 0)
                                                    .orderByDesc(ConsumerServiceInfo::getUpdatedAt);
                                            List<ConsumerServiceInfo> consumerServiceInfoList = consumerServiceInfoMapper.selectList(queryWrapper);
                                            if (!CollectionUtils.isEmpty(consumerServiceInfoList)) {
                                                ConsumerServiceInfo serviceInfo = consumerServiceInfoList.get(0);
                                                Long today = DateUtils.today().getTime();
                                                if (today == serviceInfo.getEndDate().getTime()) {
                                                    param.put("verb", "于");
                                                }  else if (today < serviceInfo.getEndDate().getTime()) {
                                                    param.put("verb", "将于");
                                                } else if (today > serviceInfo.getEndDate().getTime()) {
                                                    param.put("verb", "已于");
                                                }
                                            }
                                        }
                                    }
                                    // 公司电话
                                    QueryWrapper<BusinessNotice> query = new QueryWrapper<>();
                                    query.lambda().or().eq(BusinessNotice::getIsDeleted, 0)
                                            .eq(BusinessNotice::getSpId, informRecord.getSpId())
                                            .eq(BusinessNotice::getParamCode, BusinessNoticeParam.CM_SERVICE_HOT_LINE.getCode());
                                    List<BusinessNotice> r = noticeMapper.selectList(query);
                                    String phone = "";
                                    if (!CollectionUtil.isEmpty(r)) phone = r.get(0).getParamValue();
                                    param.put("phone", phone);
                                    String orgCode = companyService.getOrgCode(informRecord.getSpId(), informRecord.getConsumerId());
                                    Map<String, Object> requestParam = sendMessageService
                                            .getRequestParam(pushPhone
                                                    , msgType, orgCode
                                                    , param, "sms", null, null, null, 0);
                                    log.info("报警记录外呼开始发送短信callSms-ext:{}", JSONObject.toJSONString(requestParam));
                                    Map<String, Object> sms = sendMessageService
                                            .sendSms(requestParam, informRecord.getSpId());
                                    log.info("报警记录外呼开始发送短信-发送日志:{}", JSONObject.toJSONString(sms));
                                    AssembleTemplateDTO assembleTemplateDTO = new AssembleTemplateDTO();
                                    assembleTemplateDTO.setSpId(informRecord.getSpId());
                                    assembleTemplateDTO.setOrgCode(orgCode);
                                    String content = sendMessageService.getSmsContent(msgType,param,assembleTemplateDTO);
                                    if (sms.get("result").equals(true)) {
                                        //发送成功
                                        String errorMsg = "发送成功";
                                        if (sms.get("data") != null) {
                                            HashMap<String, Object> req = new HashMap<>();
                                            req.put("ids", sms.get("data"));
                                            req.put("orgCode", orgCode);
                                            try {
                                                Thread.sleep(2000L);
                                                Map<String, Object> resMap = sendMessageService.subTaskDetail(req, "");
                                                //延迟获取数据
                                                errorMsg = resMap != null ? (String) resMap.get("errorMsg") : "";
                                            } catch (InterruptedException e) {
                                                log.error("subTaskDetail-error:{}", e);
                                            }

                                        }
                                        saveInformRecord(content, errorMsg, JSONObject.toJSONString(sms.get("data")), informRecord);
                                    } else {
                                        String errMsg = (String)sms.get("errMsg");
                                        saveInformRecord(content, errMsg, JSONObject.toJSONString(sms.get("data")), informRecord);
                                    }
                                }

                            }
                        }

                    }
                }
            }

        }
    }

    private Map<String, String> queryCallInfo(List<Integer> ids, int type) {
        log.info("queryCallInfo-params:{},{}", JSONObject.toJSONString(ids), type);
        Map<String, String> taskResultMap = new HashMap<>();
        if (!CollectionUtil.isEmpty(ids)) {
            int groupSize = 50;
            if (ids.size() > groupSize) {
                int listSize = ids.size();
                for (int i = 0; i < listSize; i += groupSize) {
                    List<Integer> groupIds = ids.subList(i, Math.min(i + groupSize, listSize));
                    Map<String, String> result = handleQueryCallInfo(groupIds, type);
                    taskResultMap.putAll(result);
                }
            }else{
                Map<String, String> result = handleQueryCallInfo(ids, type);
                taskResultMap.putAll(result);
            }
        }
        log.info("queryCallInfo-result:{},{}", JSONObject.toJSONString(taskResultMap), type);
        return taskResultMap;
    }

    private Map<String, String> handleQueryCallInfo(List<Integer> ids,int type) {
        Map<String, String> taskResultMap = new HashMap<>();
        if (ids==null || ids.isEmpty()){
            return taskResultMap;
        }
        CallTaskDTO callTaskDTO = new CallTaskDTO();
        callTaskDTO.setIds(ids);
        JSONObject result = xfCallService.callSearch(callTaskDTO);
        if (result == null || CollectionUtil.isEmpty(result.getJSONArray("list"))) {
            log.error("xfCallService-error:{}", JSONObject.toJSONString(result));
            return taskResultMap;
        }
        JSONArray jsonArray = result.getJSONArray("list");
        for (Object o : jsonArray) {
            JSONObject jsonObject = JSONObject.parseObject(o + "");
            String taskResult = jsonObject.getString("task_result");
            int code = StringUtil.isEmpty(taskResult) || Integer.parseInt(taskResult) == 0 ? 0 : 1;
            String desc = jsonObject.getString("task_result_desc");
            String taskDataId = jsonObject.getString("id");
            log.info("本次更新外呼回执信息：code:{},desc:{},taskDataId:{}", code, desc, taskDataId);
            taskResultMap.put(taskDataId, taskResult);
            if (type == 0) {
                if (!StringUtils.isEmpty(taskResult)) {
                    warningRecordMapper.updateByTaskDataId(taskDataId, code, desc);
                }
            } else if (type == 1) {
                if (!StringUtils.isEmpty(taskResult)) {
                    runningRecordMapper.updateByTaskDataId(taskDataId, code, desc);
                }
            } else {
                if (!StringUtils.isEmpty(taskResult)) {
                    informRecordMapper.updateByTaskDataId(taskDataId, code, desc);
                }
            }
        }
        return taskResultMap;
    }

    //存储报警记录
    public void saveWarningRecord(String content, Object errorMsg, String receiptCode, WarningRecord warning) {

        WarningRecord warningRecord = new WarningRecord();
        warningRecord.setStatus(2);
        warningRecord.setParentId(warning.getId());
        warningRecord.setConsumerId(warning.getConsumerId());
        warningRecord.setStartTime(warning.getStartTime());
        warningRecord.setWarningStartTime(warning.getWarningStartTime());
        warningRecord.setTriggerRuleId(warning.getTriggerRuleId());
        warningRecord.setIMEI(warning.getIMEI());
        warningRecord.setTaskIdentificationCode(warning.getTaskIdentificationCode());
        warningRecord.setConcentration(warning.getConcentration());
        warningRecord.setType(warning.getType());
        warningRecord.setSendType(5);
        warningRecord.setObjLevel(warning.getObjLevel());
        warningRecord.setSpId(warning.getSpId());
        warningRecord.setSendResult(!StringUtils.isEmpty(errorMsg) ? 1 : 0);
        warningRecord.setContent(content);
        warningRecord.setReceiptCode(receiptCode);
        warningRecord.setNotifyObjInfo(warning.getNotifyObjInfo());
        warningRecord.setNotifyObjType(warning.getNotifyObjType());
        warningRecord.setPushPhone(warning.getPushPhone());
        warningRecord.setSupIMEI(warning.getSupIMEI());
        warningRecord.setNotifyFrom(0);
        warningRecord.setRemark(!StringUtils.isEmpty(errorMsg) ? errorMsg + "" : "发送成功");

        log.info("saveWarningRecord:{}", JSONObject.toJSONString(warningRecord));
        warningRecordMapper.insert(warningRecord);
    }

    //存储运行报告记录
    public void saveRunningRecord(String content, Object errorMsg, String receiptCode, RunningRecord runningRecord) {

        RunningRecord record = new RunningRecord();
        record.setStatus(1);
        record.setParentId(runningRecord.getId());
        record.setConsumerId(runningRecord.getConsumerId());
        record.setStartTime(runningRecord.getStartTime());
        record.setEndTime(runningRecord.getEndTime());
        record.setTriggerRuleId(runningRecord.getTriggerRuleId());
        record.setPushPhone(runningRecord.getPushPhone());
        record.setTaskIdentificationCode(runningRecord.getTaskIdentificationCode());
        record.setSendType(4);
        record.setObjLevel(runningRecord.getObjLevel());
        record.setSpId(runningRecord.getSpId());
        record.setSendResult(!StringUtils.isEmpty(errorMsg) ? 1 : 0);
        record.setContent(content);
        record.setReceiptCode(receiptCode);
        record.setRemark(!StringUtils.isEmpty(errorMsg) ? errorMsg + "" : "发送成功");

        log.info("saveRunningRecord:{}", JSONObject.toJSONString(record));
        runningRecordMapper.insert(record);
    }

    //存储运行报告记录
    public void saveInformRecord(String content, Object errorMsg, String receiptCode, InformRecord informRecord) {

        InformRecord record = new InformRecord();
        record.setStatus(1);
        record.setIMEI(informRecord.getIMEI());
        record.setParentId(informRecord.getId());
        record.setConsumerId(informRecord.getConsumerId());
        record.setStartTime(informRecord.getStartTime());
        record.setEndTime(informRecord.getEndTime());
        record.setTriggerRuleId(informRecord.getTriggerRuleId());
        record.setPushPhone(informRecord.getPushPhone());
        record.setTaskIdentificationCode(informRecord.getTaskIdentificationCode());
        record.setSendType(4);
        record.setObjLevel(informRecord.getObjLevel());
        record.setSpId(informRecord.getSpId());
        record.setSendResult(!StringUtils.isEmpty(errorMsg) ? 1 : 0);
        record.setContent(content);
        record.setReceiptCode(receiptCode);
        record.setRemark(!StringUtils.isEmpty(errorMsg) ? errorMsg + "" : "发送成功");

        log.info("saveInformRecord:{}", JSONObject.toJSONString(record));
        informRecordMapper.insert(record);
    }

    //告警
    public String getSmsWarningTemplate(Map<String, Object> param, WarningRecord warningRecord, String phone, String smsContent) {
        return smsContent.replace("#Time#", warningRecord.getWarningStartTime() == null ? "" : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(warningRecord.getWarningStartTime()))
                .replace("#Name#", param.get("Name") + "")
                .replace("#Position#", param.get("position") + "")
                .replace("#Equipmenttype#", param.get("Equipmenttype") + "")
                .replace("#subsName#", param.get("subsName") + "")
                .replace("#address#", param.get("address") + "")
                .replace("#IMEI#", param.get("IMEI") + "")
                .replace("#phone#", phone == null ? "" : phone);

    }

    //故障
    public String getSmsFaultTemplate(Map<String, Object> param, InformRecord informRecord, String phone) {
        return Constants.FAULT_SMS_MESSAGES_CONTENT.replace("#Time#", informRecord.getStartTime() == null ? "" : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(informRecord.getStartTime()))
                .replace("#Name#", param.get("Name") + "")
                .replace("#Position#", param.get("Position") + "")
                .replace("#Equipmenttype#", param.get("Equipmenttype") + "")
                .replace("#subsName#", param.get("subsName") + "")
                .replace("#address#", param.get("address") + "")
                .replace("#phone#", phone == null ? "" : phone);

    }

    //离线
    public String getSmsRestTemplate(Map<String, Object> param, InformRecord informRecord, String phone) {
        return Constants.REST_SMS_MESSAGES_CONTENT.replace("#Time#", informRecord.getStartTime() == null ? "" : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(informRecord.getStartTime()))
                .replace("#Name#", param.get("Name") + "")
                .replace("#Position#", param.get("Position") + "")
                .replace("#Equipmenttype#", param.get("Equipmenttype") + "")
                .replace("#subsName#", param.get("subsName") + "")
                .replace("#address#", param.get("address") + "")
                .replace("#phone#", phone == null ? "" : phone);

    }

    //服务到期
    public String getSmsServiceTemplate(Map<String, Object> param, InformRecord informRecord, String phone) {
        return Constants.SERVICE_SMS_MESSAGES_CONTENT.replace("#Time#", informRecord.getStartTime() == null ? "" : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(informRecord.getStartTime()))
                .replace("#Name#", param.get("Name") + "")
                .replace("#Position#", param.get("Position") + "")
                .replace("#Equipmenttype#", param.get("Equipmenttype") + "")
                .replace("#subsName#", param.get("subsName") + "")
                .replace("#address#", param.get("address") + "")
                .replace("#phone#", phone == null ? "" : phone);

    }

    //故障、离线、服务到期
    public String getSmsIoformTemplate(Map<String, Object> param, InformRecord informRecord, String phone, String smsContent) {
        return smsContent.replace("#Time#", informRecord.getStartTime() == null ? "" : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(informRecord.getStartTime()))
                .replace("#Name#", param.get("Name") + "")
                .replace("#Position#", param.get("Position") + "")
                .replace("#Equipmenttype#", param.get("Equipmenttype") + "")
                .replace("#subsName#", param.get("subsName") + "")
                .replace("#address#", param.get("address") + "")
                .replace("#phone#", phone == null ? "" : phone);

    }

    //运行报告
    public String getSmsRunningTemplate(Map<String, Object> param, RunningRecord runningRecord, String phone, String smsContent) {
        return smsContent.replace("#Family#", param.get("Family") + "")
                .replace("#Time#", runningRecord.getStartTime() == null ? "" : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(runningRecord.getStartTime()))
                .replace("#phone#", phone == null ? "" : phone);

    }

}
